﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using AutoPartsSearch.Domain.Abstract;
using AutoPartsSearch.Domain.Abstract.Repositories;
using AutoPartsSearch.Domain.Entities.Enums;
using AutoPartsSearch.Domain.Entities;
using AutoPartsSearch.Domain.Common;

namespace AutoPartsSearch.Domain.Concrete.Repositories
{
    public class DapperDictionaryRepository : BaseRepository, IDictionaryRepository
    {
        public DapperDictionaryRepository(ILanguageGetter languageGetter)
            : base(languageGetter)
        {
        }

        public int Add(Entities.Dictionary instance)
        {
            var id = -1;
            var param = new Dapper.DynamicParameters();
            param.Add("@Id", id, DbType.Int32, ParameterDirection.Output);
            param.Add("@TypeId", instance.Type, DbType.Int32);
            param.Add("@Ru", instance.Name.Ru, DbType.String);
            param.Add("@Ro", instance.Name.Ro, DbType.String);
            param.Add("@En", instance.Name.En, DbType.String);
            param.Add("@ParentId", instance.ParentId, DbType.Int32);
            param.Add("@AdditionalParentId", instance.AdditionalParentId, DbType.Int32);

            QueryExecutor.ExecuteProcedure("sp_AddDictionary", param);
            id = param.Get<int>("@Id");
            return id;
        }

        public void Update(Entities.Dictionary instance)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Id", instance.Id, DbType.Int32);
            param.Add("@TypeId", instance.Type, DbType.Int32);
            param.Add("@Ru", instance.Name.Ru, DbType.String);
            param.Add("@Ro", instance.Name.Ro, DbType.String);
            param.Add("@En", instance.Name.En, DbType.String);
            param.Add("@ParentId", instance.ParentId, DbType.Int32);
            param.Add("@AdditionalParentId", instance.AdditionalParentId, DbType.Int32);
            QueryExecutor.ExecuteProcedure("sp_UpdateDictionary", param);
        }

        public Entities.Dictionary GetById(int id)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Id", id, DbType.Int32);
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            return QueryExecutor.QueryDynamic<Dictionary>("sp_GetDictionaryById", ModelEditReader, param).FirstOrDefault();
        }

        public IEnumerable<Entities.Dictionary> Get()
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            return QueryExecutor.QueryDynamic<Dictionary>("sp_GetDictionaries", ModelEditReader, param);
        }

        public IEnumerable<Dictionary> GetByParentId(int parentId)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@ParentId", parentId, DbType.Int32);
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            return QueryExecutor.QueryDynamic<Dictionary>("sp_GetDictionariesByParentId", ModelReader, param);
        }

        public IEnumerable<Dictionary> GetByType(DictionaryType type)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@TypeId", type, DbType.Int32);
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            return QueryExecutor.QueryDynamic<Dictionary>("sp_GetDictionariesByType", ModelReader, param);
        }

        public IEnumerable<Dictionary> GetByParentType(DictionaryType type)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@TypeId", type, DbType.Int32);
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            return QueryExecutor.QueryDynamic<Dictionary>("sp_GetDictionariesByParentType", ModelReader, param);
        }

        public IEnumerable<Dictionary> GetByAdditionalParentType(DictionaryType type)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@TypeId", type, DbType.Int32);
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            return QueryExecutor.QueryDynamic<Dictionary>("sp_GetDictionariesByAdditionalParentType", ModelReader, param);
        }

        public IEnumerable<Dictionary> GetByDictionaryTypeParent(DictionaryType type)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@TypeId", type, DbType.Int32);
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            return QueryExecutor.QueryDynamic<Dictionary>("sp_GetDictionariesByDictionaryTypesParent", ModelReader, param);
        }

        public IEnumerable<Entities.Dictionary> Get(int page, int pageSize)
        {
            throw new NotImplementedException();
        }

        public void Delete(int id)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Id", id, DbType.Int32);
            QueryExecutor.ExecuteProcedure("sp_DeleteDictionary", param);
        }

        public long GetTotalCount()
        {
            throw new NotImplementedException();
        }

        private void ModelReader(Dictionary dictionary, dynamic o)
        {
            dictionary.Id = o.Id;
            dictionary.Type = (DictionaryType) o.Type;
            dictionary.Name = new Localization(o.Name);
            dictionary.ParentId = o.ParentId;
            dictionary.ParentName = new Localization(o.ParentName);
            dictionary.AdditionalParentId = o.AdditionalParentId;
            dictionary.AdditionalParentName = o.AdditionalParentName;
        }

        private void ModelEditReader(Dictionary dictionary, dynamic o)
        {
            dictionary.Id = o.Id;
            dictionary.Type = (DictionaryType)o.Type;
            dictionary.Name = new Localization
                                  {
                                      Ru = o.Ru,
                                      Ro = o.Ro,
                                      En = o.En,
                                      Default = o.Default
                                  };
            dictionary.ParentId = o.ParentId;
            dictionary.ParentName = new Localization(o.ParentName);
            dictionary.AdditionalParentId = o.AdditionalParentId;
            dictionary.AdditionalParentName = o.AdditionalParentName;
        }

    }
}
